<template>
  <view class="container">
    <view class="title">Canvas 绘制可爱猫猫</view>

    <!-- 绘图区域 -->
    <view class="canvas-box">
      <canvas type="2d" canvas-id="catCanvas" class="cat-canvas" @ready="initCanvas"></canvas>
    </view>

    <!-- 控制按钮 -->
    <view class="control-panel">
      <button class="btn" @click="drawCat">绘制猫猫</button>
      <button class="btn btn-secondary" @click="clearCanvas">清空画布</button>
      <button class="btn btn-tertiary" @click="changeColor">更换颜色</button>
    </view>
  </view>
</template>

<script setup>
  import {
    ref
  } from 'vue';
  import {
    createCanvasContext
  } from '@dcloudio/uni-app';

  // Canvas相关变量
  const ctx = ref(null);
  const canvasWidth = ref(0);
  const canvasHeight = ref(0);
  const centerX = ref(0);
  const centerY = ref(0);

  // 猫猫样式变量
  const catColors = [{
      primary: '#ffcc99',
      secondary: '#e69966',
      accent: '#ff99cc'
    }, // 橘猫
    {
      primary: '#d9d9d9',
      secondary: '#b3b3b3',
      accent: '#ffb3b3'
    }, // 灰猫
    {
      primary: '#ffffff',
      secondary: '#e6e6e6',
      accent: '#ffcceb'
    }, // 白猫
    {
      primary: '#333333',
      secondary: '#1a1a1a',
      accent: '#ff99cc'
    } // 黑猫
  ];
  const currentColorIndex = ref(0);
  const catSize = ref(1.0); // 缩放比例

  // 初始化Canvas
  const initCanvas = (e) => {
    // 获取Canvas上下文
    ctx.value = createCanvasContext('catCanvas', this);

    // 获取Canvas尺寸
    const {
      width,
      height
    } = e.detail;
    canvasWidth.value = width;
    canvasHeight.value = height;

    // 计算中心位置
    centerX.value = width / 2;
    centerY.value = height / 2 - 50;

    // 初始绘制
    drawCat();
  };

  // 绘制猫猫主函数
  const drawCat = () => {
    if (!ctx.value) return;

    // 清除画布
    clearCanvas();

    // 获取当前颜色方案
    const colors = catColors[currentColorIndex.value];

    // 绘制顺序：从后到前
    drawBody(colors);
    drawHead(colors);
    drawEars(colors);
    drawEyes();
    drawNose(colors);
    drawMouth();
    drawWhiskers();
    drawPaws(colors);

    // 提交绘制
    ctx.value.draw();
  };

  // 绘制头部
  const drawHead = (colors) => {
    const radius = 80 * catSize.value;

    // 头部
    ctx.value.beginPath();
    ctx.value.arc(centerX.value, centerY.value, radius, 0, Math.PI * 2);
    ctx.value.setFillStyle(colors.primary);
    ctx.value.fill();
    ctx.value.setStrokeStyle(colors.secondary);
    ctx.value.setLineWidth(2);
    ctx.value.stroke();

    // 脸颊红晕
    drawCheeks(colors);
  };

  // 绘制耳朵
  const drawEars = (colors) => {
    const headRadius = 80 * catSize.value;

    // 左耳朵外轮廓
    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value - headRadius * 0.7, centerY.value - headRadius * 0.2);
    ctx.value.lineTo(centerX.value - headRadius * 0.9, centerY.value - headRadius * 1.2);
    ctx.value.lineTo(centerX.value - headRadius * 0.1, centerY.value - headRadius * 0.5);
    ctx.value.closePath();
    ctx.value.setFillStyle(colors.primary);
    ctx.value.fill();
    ctx.value.setStrokeStyle(colors.secondary);
    ctx.value.stroke();

    // 左耳朵内部
    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value - headRadius * 0.6, centerY.value - headRadius * 0.3);
    ctx.value.lineTo(centerX.value - headRadius * 0.8, centerY.value - headRadius * 1.0);
    ctx.value.lineTo(centerX.value - headRadius * 0.2, centerY.value - headRadius * 0.6);
    ctx.value.closePath();
    ctx.value.setFillStyle('#fff');
    ctx.value.fill();

    // 右耳朵外轮廓
    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value + headRadius * 0.7, centerY.value - headRadius * 0.2);
    ctx.value.lineTo(centerX.value + headRadius * 0.9, centerY.value - headRadius * 1.2);
    ctx.value.lineTo(centerX.value + headRadius * 0.1, centerY.value - headRadius * 0.5);
    ctx.value.closePath();
    ctx.value.setFillStyle(colors.primary);
    ctx.value.fill();
    ctx.value.setStrokeStyle(colors.secondary);
    ctx.value.stroke();

    // 右耳朵内部
    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value + headRadius * 0.6, centerY.value - headRadius * 0.3);
    ctx.value.lineTo(centerX.value + headRadius * 0.8, centerY.value - headRadius * 1.0);
    ctx.value.lineTo(centerX.value + headRadius * 0.2, centerY.value - headRadius * 0.6);
    ctx.value.closePath();
    ctx.value.setFillStyle('#fff');
    ctx.value.fill();
  };

  // 绘制眼睛
  const drawEyes = () => {
    const headRadius = 80 * catSize.value;
    const eyeRadius = 15 * catSize.value;

    // 左眼
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value - headRadius * 0.35,
      centerY.value - headRadius * 0.1,
      eyeRadius,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle('#fff');
    ctx.value.fill();
    ctx.value.setStrokeStyle('#333');
    ctx.value.stroke();

    // 左眼瞳孔
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value - headRadius * 0.35,
      centerY.value - headRadius * 0.1,
      eyeRadius * 0.6,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle('#333');
    ctx.value.fill();

    // 左眼高光
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value - headRadius * 0.38,
      centerY.value - headRadius * 0.15,
      eyeRadius * 0.2,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle('#fff');
    ctx.value.fill();

    // 右眼
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value + headRadius * 0.35,
      centerY.value - headRadius * 0.1,
      eyeRadius,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle('#fff');
    ctx.value.fill();
    ctx.value.setStrokeStyle('#333');
    ctx.value.stroke();

    // 右眼瞳孔
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value + headRadius * 0.35,
      centerY.value - headRadius * 0.1,
      eyeRadius * 0.6,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle('#333');
    ctx.value.fill();

    // 右眼高光
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value + headRadius * 0.38,
      centerY.value - headRadius * 0.15,
      eyeRadius * 0.2,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle('#fff');
    ctx.value.fill();
  };

  // 绘制鼻子
  const drawNose = (colors) => {
    const headRadius = 80 * catSize.value;

    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value, centerY.value + headRadius * 0.1);
    ctx.value.lineTo(centerX.value - headRadius * 0.15, centerY.value + headRadius * 0.25);
    ctx.value.lineTo(centerX.value + headRadius * 0.15, centerY.value + headRadius * 0.25);
    ctx.value.closePath();
    ctx.value.setFillStyle(colors.accent);
    ctx.value.fill();
    ctx.value.setStrokeStyle('#333');
    ctx.value.setLineWidth(1);
    ctx.value.stroke();
  };

  // 绘制嘴巴
  const drawMouth = () => {
    const headRadius = 80 * catSize.value;

    // 嘴线
    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value, centerY.value + headRadius * 0.25);
    ctx.value.quadraticCurveTo(
      centerX.value, centerY.value + headRadius * 0.45,
      centerX.value - headRadius * 0.15, centerY.value + headRadius * 0.4
    );
    ctx.value.moveTo(centerX.value, centerY.value + headRadius * 0.25);
    ctx.value.quadraticCurveTo(
      centerX.value, centerY.value + headRadius * 0.45,
      centerX.value + headRadius * 0.15, centerY.value + headRadius * 0.4
    );
    ctx.value.setStrokeStyle('#333');
    ctx.value.setLineWidth(1.5);
    ctx.value.stroke();
  };

  // 绘制胡须
  const drawWhiskers = () => {
    const headRadius = 80 * catSize.value;

    ctx.value.setStrokeStyle('#666');
    ctx.value.setLineWidth(1);

    // 左胡须
    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value - headRadius * 0.15, centerY.value + headRadius * 0.25);
    ctx.value.lineTo(centerX.value - headRadius * 0.6, centerY.value + headRadius * 0.2);
    ctx.value.stroke();

    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value - headRadius * 0.15, centerY.value + headRadius * 0.3);
    ctx.value.lineTo(centerX.value - headRadius * 0.7, centerY.value + headRadius * 0.3);
    ctx.value.stroke();

    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value - headRadius * 0.15, centerY.value + headRadius * 0.35);
    ctx.value.lineTo(centerX.value - headRadius * 0.6, centerY.value + headRadius * 0.4);
    ctx.value.stroke();

    // 右胡须
    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value + headRadius * 0.15, centerY.value + headRadius * 0.25);
    ctx.value.lineTo(centerX.value + headRadius * 0.6, centerY.value + headRadius * 0.2);
    ctx.value.stroke();

    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value + headRadius * 0.15, centerY.value + headRadius * 0.3);
    ctx.value.lineTo(centerX.value + headRadius * 0.7, centerY.value + headRadius * 0.3);
    ctx.value.stroke();

    ctx.value.beginPath();
    ctx.value.moveTo(centerX.value + headRadius * 0.15, centerY.value + headRadius * 0.35);
    ctx.value.lineTo(centerX.value + headRadius * 0.6, centerY.value + headRadius * 0.4);
    ctx.value.stroke();
  };

  // 绘制身体
  const drawBody = (colors) => {
    const bodyWidth = 120 * catSize.value;
    const bodyHeight = 100 * catSize.value;

    // 身体椭圆
    ctx.value.save();
    ctx.value.translate(centerX.value, centerY.value + 120 * catSize.value);
    ctx.value.scale(1, 0.7);
    ctx.value.beginPath();
    ctx.value.arc(0, 0, bodyWidth, 0, Math.PI * 2);
    ctx.value.restore();
    ctx.value.setFillStyle(colors.primary);
    ctx.value.fill();
    ctx.value.setStrokeStyle(colors.secondary);
    ctx.value.setLineWidth(2);
    ctx.value.stroke();
  };

  // 绘制爪子
  const drawPaws = (colors) => {
    const pawRadius = 25 * catSize.value;

    // 左前爪
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value - 60 * catSize.value,
      centerY.value + 140 * catSize.value,
      pawRadius,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle(colors.primary);
    ctx.value.fill();
    ctx.value.setStrokeStyle(colors.secondary);
    ctx.value.stroke();

    // 右前爪
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value + 60 * catSize.value,
      centerY.value + 140 * catSize.value,
      pawRadius,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle(colors.primary);
    ctx.value.fill();
    ctx.value.setStrokeStyle(colors.secondary);
    ctx.value.stroke();

    // 爪子细节
    drawPawDetails(centerX.value - 60 * catSize.value, centerY.value + 140 * catSize.value);
    drawPawDetails(centerX.value + 60 * catSize.value, centerY.value + 140 * catSize.value);
  };

  // 绘制爪子细节
  const drawPawDetails = (x, y) => {
    const padSize = 8 * catSize.value;

    ctx.value.setFillStyle('#fff');

    // 左爪垫
    ctx.value.beginPath();
    ctx.value.arc(x - padSize * 1.2, y + padSize, padSize, 0, Math.PI * 2);
    ctx.value.fill();

    // 中爪垫
    ctx.value.beginPath();
    ctx.value.arc(x, y + padSize * 1.2, padSize * 1.2, 0, Math.PI * 2);
    ctx.value.fill();

    // 右爪垫
    ctx.value.beginPath();
    ctx.value.arc(x + padSize * 1.2, y + padSize, padSize, 0, Math.PI * 2);
    ctx.value.fill();
  };

  // 绘制脸颊红晕
  const drawCheeks = (colors) => {
    const headRadius = 80 * catSize.value;

    // 左脸颊
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value - headRadius * 0.6,
      centerY.value + headRadius * 0.2,
      headRadius * 0.25,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle(colors.accent + '66'); // 添加透明度
    ctx.value.fill();

    // 右脸颊
    ctx.value.beginPath();
    ctx.value.arc(
      centerX.value + headRadius * 0.6,
      centerY.value + headRadius * 0.2,
      headRadius * 0.25,
      0,
      Math.PI * 2
    );
    ctx.value.setFillStyle(colors.accent + '66'); // 添加透明度
    ctx.value.fill();
  };

  // 清空画布
  const clearCanvas = () => {
    if (!ctx.value) return;
    ctx.value.clearRect(0, 0, canvasWidth.value, canvasHeight.value);
    ctx.value.draw();
  };

  // 更换猫猫颜色
  const changeColor = () => {
    currentColorIndex.value = (currentColorIndex.value + 1) % catColors.length;
    drawCat();
  };
</script>

<style scoped>
  .container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 20px;
    background-color: #f5f7fa;
    min-height: 100vh;
  }

  .title {
    font-size: 24px;
    font-weight: bold;
    color: #333;
    margin-bottom: 20px;
  }

  .canvas-box {
    width: 100%;
    max-width: 400px;
    background-color: #fff;
    border-radius: 12px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
    padding: 16px;
    margin-bottom: 30px;
  }

  .cat-canvas {
    width: 100%;
    height: 400px;
  }

  .control-panel {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    justify-content: center;
    width: 100%;
    max-width: 400px;
  }

  .btn {
    padding: 10px 20px;
    background-color: #4cd964;
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 16px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.3s;
  }

  .btn:hover {
    background-color: #34c759;
  }

  .btn-secondary {
    background-color: #ff9500;
  }

  .btn-secondary:hover {
    background-color: #e08400;
  }

  .btn-tertiary {
    background-color: #5856d6;
  }

  .btn-tertiary:hover {
    background-color: #4846b0;
  }
</style>